package com.cxkj.uniplugin_tts;

import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;

import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.Locale;

import io.dcloud.feature.uniapp.UniSDKInstance;
import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;

public class UniTTSModule extends UniModule {
    private TextToSpeech tts;
    private boolean isInitialized = false;
    private UniJSCallback initCallback;
    private UniJSCallback statusCallback;

    @UniJSMethod(uiThread = true)
    public void initialize(UniJSCallback callback) {
        this.initCallback = callback;
        tts = new TextToSpeech(mUniSDKInstance.getContext(), status -> {
            if (status == TextToSpeech.SUCCESS) {
                isInitialized = true;
                if (initCallback != null) {
                    initCallback.invoke(true);
                }
            } else {
                isInitialized = false;
                if (initCallback != null) {
                    initCallback.invoke(false);
                }
            }
        });

        tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
            @Override
            public void onStart(String utteranceId) {
                if (statusCallback != null) {
                    statusCallback.invoke(createError("start", utteranceId));
                }
            }

            @Override
            public void onDone(String utteranceId) {
                if (statusCallback != null) {
                    statusCallback.invoke(createError("done", utteranceId));
                }
            }

            @Override
            public void onError(String utteranceId) {
                if (statusCallback != null) {
                    statusCallback.invoke(createError("error", utteranceId));
                }
            }
        });
    }

    @UniJSMethod(uiThread = true)
    public void speak(String text, float rate, float pitch, String language, String utteranceId, UniJSCallback callback) {
        if (!isInitialized) {
            if (callback != null) {
                statusCallback.invoke(createError("error", "TTS not initialized"));
            }
            return;
        }

        try {
            Locale locale = Locale.forLanguageTag(language);
            int result = tts.setLanguage(locale);
            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                if (callback != null) {

                    statusCallback.invoke(createError("error", "Language not supported"));
                }
                return;
            }

            tts.setSpeechRate(rate);
            tts.setPitch(pitch);

            HashMap<String, String> params = new HashMap<>();
            params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);

            int speakResult = tts.speak(text, TextToSpeech.QUEUE_FLUSH, params);
            if (callback != null) {
                callback.invoke(speakResult == TextToSpeech.SUCCESS);
            }
        } catch (Exception e) {
            if (callback != null) {

                statusCallback.invoke(createError("error", e.getMessage()));
            }
        }
    }

    @UniJSMethod(uiThread = true)
    public void stop() {
        if (tts != null) {
            tts.stop();
        }
    }

    @UniJSMethod(uiThread = true)
    public void shutdown() {
        if (tts != null) {
            tts.shutdown();
            isInitialized = false;
        }
    }

    @UniJSMethod(uiThread = true)
    public void setStatusCallback(UniJSCallback callback) {
        this.statusCallback = callback;
    }

    @UniJSMethod(uiThread = true)
    public void getAvailableLanguages(UniJSCallback callback) {
        if (!isInitialized || tts == null) {
            if (callback != null) {

                statusCallback.invoke(createError("error","TTS not initialized"));
            }
            return;
        }

        try {
            Locale[] locales = Locale.getAvailableLocales();
            java.util.List<String> languages = new java.util.ArrayList<>();
            for (Locale locale : locales) {
                if (tts.isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE) {
                    languages.add(locale.toLanguageTag());
                }
            }
            if (callback != null) {

                callback.invoke(createError("true","语言"));
            }
        } catch (Exception e) {
            if (callback != null) {
                callback.invoke(createError("false","语言"));
            }
        }
    }
    // --------------------
    // 工具函数
    // --------------------

    private JSONObject createSimpleResponse(String status) {
        JSONObject res = new JSONObject();
        res.put("status", status);
        return res;
    }

    private JSONObject createErrorResponse(String status, int code, String desc) {
        JSONObject res = new JSONObject();
        res.put("status", status);
        res.put("code", code);
        res.put("message", desc);
        return res;
    }

    private JSONObject createError(String status, String message) {
        JSONObject res = new JSONObject();
        res.put("status", status);
        res.put("error", message);
        return res;
    }
    // --------------------
    // 工具函数
    // --------------------
}